// WebcamCapture
// Capture device interface implementation for OpenCV webcam capturing
// 
// FLMScan - Featured by FabLab Munich

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using FLMScan.WorldCoordinateReconstruction.Riedmaier;
using FLMScan.Parameters;
using System.ComponentModel;

namespace FLMScan.Capture
{
    internal class WebcamCapture : ICapture, IDisposable
    {        
        private bool isDisposed = false;
        // private WebcamCaptureOpenCv webcamCaptureOpenCv;
        private WebcamCaptureAForge webcamCaptureAForge;
        private BackgroundWorker backgroundWorker;

        private event EventHandler CaptureDone;

        event EventHandler ICapture.CaptureDone
        {
            add { CaptureDone += value; }
            remove { CaptureDone -= value; }
        }

        public WebcamCapture(CameraParameters cameraParameters, CameraSensorParameters cameraSensorParameters)
        {
            // webcamCaptureOpenCv = new WebcamCaptureOpenCv(cameraParameters.CameraId, cameraSensorParameters.ResolutionX, cameraSensorParameters.ResolutionY);                                            
            webcamCaptureAForge = new WebcamCaptureAForge(cameraParameters.CameraId, cameraSensorParameters.ResolutionX, cameraSensorParameters.ResolutionY);

            backgroundWorker = new BackgroundWorker();
            backgroundWorker.DoWork += new DoWorkEventHandler(DoCapture);
            backgroundWorker.RunWorkerCompleted += CaptureCompleted;                
        }

        public void Initialize()
        {
            webcamCaptureAForge.Initialize();
        }

        public bool IsConnected
        {
            get { return webcamCaptureAForge.IsConnected; }
        }

        public void GetFrame()
        {
            backgroundWorker.RunWorkerAsync();             
        }        

        // BackgroundWorker work
        private void DoCapture(object sender, DoWorkEventArgs e)        
        {                        
            e.Result = webcamCaptureAForge.GetFrame();
        }

        // BackgroundWorker callback on completion
        private void CaptureCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (CaptureDone != null)
            {
                CaptureEventArgs eventArgs = new CaptureEventArgs((CapturedFrame)e.Result);
                CaptureDone(this, eventArgs);
            }
        }

        public void Dispose()
        {
            Dispose(true);

            GC.SuppressFinalize(this); 
        }

        private void Dispose(bool disposing)
        {
            if (!isDisposed)
            {
                if (disposing)
                {
                    // webcamCaptureOpenCv.Dispose();
                    webcamCaptureAForge.Dispose();
                    isDisposed = true;                    
                }
            }
        }
    }
}
